#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
微信自动回复工具图形界面
"""

import sys
import os
import threading
import time
import json
from pathlib import Path
from typing import List, Optional

try:
    import itchat
    from itchat.content import TEXT
except ImportError as e:
    print("❌ 缺少微信机器人依赖，请安装itchat库")
    print("请运行: pip install itchat")
    sys.exit(1)

try:
    import tkinter as tk
    from tkinter import ttk, filedialog, messagebox, scrolledtext
except ImportError as e:
    print("❌ 缺少GUI依赖，请安装tkinter（通常Python自带）")
    sys.exit(1)


class WeChatAutoReplyGUI:
    """微信自动回复工具图形界面"""
    
    def __init__(self):
        self.root = tk.Tk()
        self.root.title("微信自动回复工具 v1.0")
        self.root.geometry("800x700")
        self.root.resizable(True, True)
        self.root.minsize(700, 600)
        
        # 设置图标和样式
        self.setup_style()
        
        # 初始化变量
        self.is_running = False
        self.is_wechat_logged_in = False  # 添加微信登录状态
        self.keywords = []  # 关键词列表
        self.auto_replies = {}  # 自动回复规则
        self.default_reply = tk.StringVar(value="您好，我已经收到您的消息，稍后会回复您。")
        self.reply_delay = tk.StringVar(value="2")
        self.status_var = tk.StringVar(value="就绪 - 请配置自动回复规则")
        
        # 创建界面
        self.create_widgets()
        
        # 居中显示窗口
        self.center_window()
    
    def setup_style(self):
        """设置界面样式"""
        style = ttk.Style()
        style.theme_use('clam')
        
        # 配置样式
        style.configure('Title.TLabel', font=('Arial', 16, 'bold'))
        style.configure('Heading.TLabel', font=('Arial', 10, 'bold'))
        style.configure('Status.TLabel', font=('Arial', 9))
    
    def center_window(self):
        """使窗口居中显示"""
        self.root.update_idletasks()
        width = self.root.winfo_width()
        height = self.root.winfo_height()
        x = (self.root.winfo_screenwidth() // 2) - (width // 2)
        y = (self.root.winfo_screenheight() // 2) - (height // 2)
        self.root.geometry(f'{width}x{height}+{x}+{y}')
    
    def create_widgets(self):
        """创建界面组件"""
        # 主框架
        main_frame = ttk.Frame(self.root, padding="10")
        main_frame.grid(row=0, column=0, sticky="nsew")
        
        # 配置网格权重
        self.root.columnconfigure(0, weight=1)
        self.root.rowconfigure(0, weight=1)
        main_frame.columnconfigure(1, weight=1)
        main_frame.rowconfigure(6, weight=1)  # 让规则列表区域可扩展
        
        # 标题
        title_label = ttk.Label(main_frame, text="微信自动回复工具", style='Title.TLabel')
        title_label.grid(row=0, column=0, columnspan=3, pady=(0, 10))
        
        # 默认回复设置区域
        self.create_default_reply_area(main_frame)
        
        # 回复延迟设置区域
        self.create_delay_setting_area(main_frame)
        
        # 关键词回复规则区域
        self.create_keyword_rules_area(main_frame)
        
        # 操作按钮区域
        self.create_action_buttons(main_frame)
        
        # 规则列表区域
        self.create_rules_list_area(main_frame)
        
        # 状态栏
        self.create_status_bar(main_frame)
    
    def create_default_reply_area(self, parent):
        """创建默认回复设置区域"""
        row = 1
        
        # 标题
        ttk.Label(parent, text="默认回复设置:", style='Heading.TLabel').grid(
            row=row, column=0, columnspan=3, sticky="w", pady=(0, 5)
        )
        
        # 默认回复输入框
        ttk.Label(parent, text="默认回复内容:").grid(
            row=row+1, column=0, sticky="w", pady=(0, 5)
        )
        
        self.default_reply_entry = ttk.Entry(parent, textvariable=self.default_reply, width=50)
        self.default_reply_entry.grid(row=row+1, column=1, columnspan=2, sticky="ew", pady=(0, 10))
    
    def create_delay_setting_area(self, parent):
        """创建回复延迟设置区域"""
        row = 3
        
        # 标题
        ttk.Label(parent, text="回复延迟设置:", style='Heading.TLabel').grid(
            row=row, column=0, columnspan=3, sticky="w", pady=(0, 5)
        )
        
        # 延迟设置
        delay_frame = ttk.Frame(parent)
        delay_frame.grid(row=row+1, column=0, columnspan=3, sticky="w", pady=(0, 10))
        
        ttk.Label(delay_frame, text="回复延迟(秒):").pack(side=tk.LEFT)
        self.delay_spinbox = ttk.Spinbox(delay_frame, from_=0, to=60, width=10, textvariable=self.reply_delay)
        self.delay_spinbox.pack(side=tk.LEFT, padx=(5, 0))
        ttk.Label(delay_frame, text="(0-60秒)").pack(side=tk.LEFT, padx=(5, 0))
    
    def create_keyword_rules_area(self, parent):
        """创建关键词回复规则区域"""
        row = 5
        
        # 标题
        ttk.Label(parent, text="关键词回复规则:", style='Heading.TLabel').grid(
            row=row, column=0, columnspan=3, sticky="w", pady=(0, 5)
        )
        
        # 关键词和回复输入框
        keyword_frame = ttk.Frame(parent)
        keyword_frame.grid(row=row+1, column=0, columnspan=3, sticky="ew", pady=(0, 10))
        keyword_frame.columnconfigure(1, weight=1)
        keyword_frame.columnconfigure(3, weight=1)
        
        ttk.Label(keyword_frame, text="关键词:").grid(row=0, column=0, sticky="w")
        self.keyword_entry = ttk.Entry(keyword_frame, width=20)
        self.keyword_entry.grid(row=0, column=1, sticky="ew", padx=(5, 10))
        
        ttk.Label(keyword_frame, text="回复内容:").grid(row=0, column=2, sticky="w")
        self.reply_entry = ttk.Entry(keyword_frame, width=20)
        self.reply_entry.grid(row=0, column=3, sticky="ew", padx=(5, 0))
        
        # 添加规则按钮
        ttk.Button(keyword_frame, text="添加规则", command=self.add_rule).grid(
            row=0, column=4, padx=(10, 0)
        )
    
    def create_action_buttons(self, parent):
        """创建操作按钮"""
        row = 7
        
        button_frame = ttk.Frame(parent)
        button_frame.grid(row=row, column=0, columnspan=3, pady=(0, 10))
        
        self.start_button = ttk.Button(button_frame, text="开始自动回复", command=self.start_auto_reply)
        self.start_button.pack(side=tk.LEFT, padx=(0, 5))
        
        self.stop_button = ttk.Button(button_frame, text="停止自动回复", command=self.stop_auto_reply, state=tk.DISABLED)
        self.stop_button.pack(side=tk.LEFT, padx=(0, 5))
        
        ttk.Button(button_frame, text="保存配置", command=self.save_config).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(button_frame, text="加载配置", command=self.load_config).pack(side=tk.LEFT, padx=(0, 5))
        ttk.Button(button_frame, text="清空规则", command=self.clear_rules).pack(side=tk.LEFT)
    
    def create_rules_list_area(self, parent):
        """创建规则列表区域"""
        row = 8
        
        # 标题
        ttk.Label(parent, text="已配置的回复规则:", style='Heading.TLabel').grid(
            row=row, column=0, sticky="w", pady=(0, 5)
        )
        
        # 规则列表框架
        list_frame = ttk.Frame(parent)
        list_frame.grid(row=row+1, column=0, columnspan=3, sticky="nsew", pady=(0, 10))
        list_frame.columnconfigure(0, weight=1)
        list_frame.rowconfigure(0, weight=1)
        
        # 创建Treeview来显示规则列表
        columns = ("关键词", "回复内容")
        self.rules_tree = ttk.Treeview(list_frame, columns=columns, show="headings", height=8)
        
        # 定义列标题
        for col in columns:
            self.rules_tree.heading(col, text=col)
            self.rules_tree.column(col, width=200)
        
        # 滚动条
        scrollbar_y = ttk.Scrollbar(list_frame, orient="vertical", command=self.rules_tree.yview)
        scrollbar_x = ttk.Scrollbar(list_frame, orient="horizontal", command=self.rules_tree.xview)
        self.rules_tree.configure(yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set)
        
        # 布局
        self.rules_tree.grid(row=0, column=0, sticky="nsew")
        scrollbar_y.grid(row=0, column=1, sticky="ns")
        scrollbar_x.grid(row=1, column=0, sticky="ew")
        
        # 删除规则按钮
        delete_frame = ttk.Frame(parent)
        delete_frame.grid(row=row+2, column=0, columnspan=3, sticky="w", pady=(0, 10))
        ttk.Button(delete_frame, text="删除选中规则", command=self.delete_selected_rule).pack(side=tk.LEFT)
    
    def create_status_bar(self, parent):
        """创建状态栏"""
        row = 10
        
        # 状态栏框架
        status_frame = ttk.Frame(parent)
        status_frame.grid(row=row, column=0, columnspan=3, sticky="ew", pady=(10, 0))
        
        # 状态标签
        self.status_bar = ttk.Label(status_frame, textvariable=self.status_var, style='Status.TLabel')
        self.status_bar.pack(side=tk.LEFT)
    
    def add_rule(self):
        """添加回复规则"""
        keyword = self.keyword_entry.get().strip()
        reply = self.reply_entry.get().strip()
        
        if not keyword or not reply:
            messagebox.showwarning("警告", "请填写关键词和回复内容")
            return
        
        # 检查关键词是否已存在
        for item in self.rules_tree.get_children():
            values = self.rules_tree.item(item, "values")
            if values[0] == keyword:
                messagebox.showwarning("警告", f"关键词 '{keyword}' 已存在")
                return
        
        # 添加到列表
        self.rules_tree.insert("", "end", values=(keyword, reply))
        
        # 清空输入框
        self.keyword_entry.delete(0, tk.END)
        self.reply_entry.delete(0, tk.END)
        
        self.status_var.set(f"已添加规则: {keyword} -> {reply}")
    
    def delete_selected_rule(self):
        """删除选中的规则"""
        selected = self.rules_tree.selection()
        if not selected:
            messagebox.showwarning("警告", "请先选择要删除的规则")
            return
        
        # 删除选中的规则
        for item in selected:
            values = self.rules_tree.item(item, "values")
            self.rules_tree.delete(item)
            self.status_var.set(f"已删除规则: {values[0]}")
    
    def clear_rules(self):
        """清空所有规则"""
        if messagebox.askyesno("确认", "确定要清空所有规则吗？"):
            for item in self.rules_tree.get_children():
                self.rules_tree.delete(item)
            self.status_var.set("已清空所有规则")
    
    def save_config(self):
        """保存配置"""
        # 获取所有规则
        rules = []
        for item in self.rules_tree.get_children():
            values = self.rules_tree.item(item, "values")
            rules.append({
                "keyword": values[0],
                "reply": values[1]
            })
        
        # 创建配置字典
        config = {
            "default_reply": self.default_reply.get(),
            "reply_delay": int(self.reply_delay.get()),
            "rules": rules
        }
        
        # 选择保存文件位置
        file_path = filedialog.asksaveasfilename(
            title="保存配置文件",
            defaultextension=".json",
            filetypes=[("JSON文件", "*.json"), ("所有文件", "*.*")]
        )
        
        if file_path:
            try:
                with open(file_path, "w", encoding="utf-8") as f:
                    json.dump(config, f, ensure_ascii=False, indent=2)
                messagebox.showinfo("成功", "配置保存成功")
                self.status_var.set("配置已保存")
            except Exception as e:
                messagebox.showerror("错误", f"保存配置失败: {str(e)}")
                self.status_var.set("保存配置失败")
    
    def load_config(self):
        """加载配置"""
        # 选择配置文件
        file_path = filedialog.askopenfilename(
            title="选择配置文件",
            filetypes=[("JSON文件", "*.json"), ("所有文件", "*.*")]
        )
        
        if file_path:
            try:
                with open(file_path, "r", encoding="utf-8") as f:
                    config = json.load(f)
                
                # 清空现有规则
                self.clear_rules()
                
                # 设置默认回复和延迟
                self.default_reply.set(config.get("default_reply", "您好，我已经收到您的消息，稍后会回复您。"))
                self.reply_delay.set(str(config.get("reply_delay", 2)))
                
                # 添加规则
                for rule in config.get("rules", []):
                    self.rules_tree.insert("", "end", values=(rule["keyword"], rule["reply"]))
                
                messagebox.showinfo("成功", "配置加载成功")
                self.status_var.set("配置已加载")
            except Exception as e:
                messagebox.showerror("错误", f"加载配置失败: {str(e)}")
                self.status_var.set("加载配置失败")
    
    def start_auto_reply(self):
        """开始自动回复"""
        # 获取所有规则
        rules = {}
        for item in self.rules_tree.get_children():
            values = self.rules_tree.item(item, "values")
            rules[values[0]] = values[1]
        
        if not rules:
            messagebox.showwarning("警告", "请先添加至少一条回复规则")
            return
        
        # 更新界面状态
        self.is_running = True
        self.start_button.config(state=tk.DISABLED)
        self.stop_button.config(state=tk.NORMAL)
        self.status_var.set("正在登录微信...")
        
        # 在新线程中执行微信登录和自动回复逻辑
        thread = threading.Thread(target=self._wechat_auto_reply_process, args=(rules,))
        thread.daemon = True
        thread.start()
    
    def stop_auto_reply(self):
        """停止自动回复"""
        self.is_running = False
        # 登出微信
        try:
            itchat.logout()
            self.is_wechat_logged_in = False
        except:
            pass
        self.start_button.config(state=tk.NORMAL)
        self.stop_button.config(state=tk.DISABLED)
        self.status_var.set("自动回复已停止")
    
    def _wechat_auto_reply_process(self, rules):
        """微信自动回复的实际处理过程"""
        try:
            default_reply = self.default_reply.get()
            delay = int(self.reply_delay.get())
            
            # 保存self引用以便在内部函数中使用
            gui_instance = self
            
            # 设置微信消息处理函数
            @itchat.msg_register(TEXT)
            def text_reply(msg):
                # 如果已停止，则不处理消息
                if not gui_instance.is_running:
                    return
                
                # 获取消息内容
                received_message = msg['Text']
                from_user = msg['FromUserName']
                
                # 查找匹配的回复规则
                reply_content = None
                for keyword, reply in rules.items():
                    if keyword in received_message:
                        reply_content = reply
                        break
                
                # 如果没有匹配的规则，使用默认回复
                if not reply_content:
                    reply_content = default_reply
                
                # 延迟回复
                time.sleep(delay)
                
                # 发送回复
                itchat.send(reply_content, toUserName=from_user)
                
                # 更新状态栏
                gui_instance.root.after(0, lambda msg=received_message, reply=reply_content: 
                               gui_instance.status_var.set(f"收到消息: {msg} -> 回复: {reply}"))
            
            # 登录微信
            self.root.after(0, lambda: self.status_var.set("请在手机上扫码登录微信..."))
            itchat.auto_login(hotReload=True, statusStorageDir='wechat_status.pkl')
            self.is_wechat_logged_in = True
            
            self.root.after(0, lambda: self.status_var.set("微信登录成功，自动回复已启动，正在监听消息..."))
            
            # 开始监听消息
            itchat.run()
            
        except Exception as e:
            self.root.after(0, lambda: messagebox.showerror("错误", f"微信自动回复过程出错: {str(e)}"))
            self.root.after(0, lambda: self.stop_auto_reply())

def main():
    """主函数"""
    app = WeChatAutoReplyGUI()
    app.root.mainloop()

if __name__ == "__main__":
    main()